package com.project.voicememoassistant.service.impl;

import com.project.voicememoassistant.config.AipNlpConfig;
import com.project.voicememoassistant.mapper.*;
import com.project.voicememoassistant.model.*;
import com.project.voicememoassistant.service.ListenService;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.*;

@Slf4j
@Service
public class ListenServiceImpl implements ListenService {
    @Resource
    private RemindMapper remindMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private PermanentMapper permanentMapper;
    @Resource
    private AipNlpConfig aipNlpConfig;
    @Resource
    private LedgerMapper ledgerMapper;
    @Resource
    private MenstruationMapper menstruationMapper;

    public String InsertSchedule(String context, String uid) throws ParseException {
        String beforeTime = null;
        String things = null;
        Date afterTime = new Date();
        //提醒类型
        int remindType = 1;
        if (context.contains("生日")) {
            remindType = 3;
        } else if (context.contains("倒数")) {
            context = context.substring(4);
            remindType = 2;
        }
        String[] output = context.split("提醒我");
        beforeTime = output[0];//解析出来的时间（未处理）
        things = output[1]; //解析出来的事件（未入表）

        if (context.contains("月")) {//针对月日的提醒
            if (output.length != 0) {
                afterTime = timeChange(beforeTime);
                int result = insert2Remind(afterTime, things, uid, remindType);
            }
            userMapper.selectByPrimaryKey(uid);
            String respone = "好的！我会在" + beforeTime + "提醒你" + things;
            return respone;
        } else if (context.contains("星期") || context.contains("周")) {//针对星期
            Date afterTime1 = String2Week(beforeTime);
            if (context.contains("生日")) {
                remindType = 3;
            }
            int result = insert2Remind(afterTime1, things, uid, remindType);
            String respone = "好的！我会在" + beforeTime + "提醒你" + things;
            return respone;
        } else if (context.contains("今天") || context.contains("明天")) {//针对今天明天
            if (context.contains("今天")) {
                if (context.contains("下午")) {
                    if (context.contains("点")) {
                        if (context.contains("分")) {//下午：点分提醒
                            Integer min = changeS2I(subString(context, "点", "分"));
                            Integer clock = changeS2I(subString(context, "下午", "点"));
                            log.info(min + clock + "===============");
                            Date afterTime2 = getClockMinDate(clock, min);
                            log.info(String.valueOf(afterTime2));
                            int result = insert2Remind(afterTime2, things, uid, remindType);
                            String respone = "好的！我会在今天下午" + clock + "点" + min + "分提醒你" + things;
                            return respone;
                        } else {  //整点提醒（今天下午）
                            Integer clock = changeS2I(subString(context, "下午", "点提醒"));
                            Date afterTime2 = getClockDate(clock);
                            int result = insert2Remind(afterTime2, things, uid, remindType);
                            String respone = "好的！我会在今天下午" + clock + "点提醒你" + things;
                            return respone;
                        }
                    } else if (context.contains(":")) {//时间格式为12:30
                        String time = subString(context, "下午", "提醒我");
                        String[] strarray = time.split(":");
                        int clock = Integer.parseInt(strarray[0]);
                        int min = Integer.parseInt(strarray[1]);
                        log.info("小时分钟按冒号=====" + clock + min);
                        Date afterTime2 = getClockMinDate(clock, min);
                        log.info(String.valueOf(afterTime2));
                        int result = insert2Remind(afterTime2, things, uid, remindType);
                        String respone = "好的！我会在今天下午" + clock + "点" + min + "分提醒你" + things;
                        return respone;
                    }
                } else if (context.contains("晚上")) {
                    if (context.contains("点")) {
                        if (context.contains("分")) {
                            Integer min = changeS2I(subString(context, "点", "分"));
                            Integer clock = changeS2I(subString(context, "晚上", "点"));
                            log.info(min + clock + "===============");
                            Date afterTime2 = getClockMinDate(clock, min);
                            log.info(String.valueOf(afterTime2));
                            int result = insert2Remind(afterTime2, things, uid, remindType);
                            String respone = "好的！我会在今天晚上" + clock + "点" + min + "分提醒你" + things;
                            return respone;
                        } else {
                            Integer clock = changeS2I(subString(context, "晚上", "点提醒"));
                            Date afterTime2 = getClockDate(clock);

                            int result = insert2Remind(afterTime2, things, uid, remindType);
                            String respone = "好的！我会在今天晚上" + clock + "点提醒你" + things;
                            return respone;
                        }
                    }
                    else if (context.contains(":")) {//时间格式为12:30
                        String time = subString(context, "晚上", "提醒我");
                        String[] strarray = time.split(":");
                        int clock = Integer.parseInt(strarray[0]);
                        int min = Integer.parseInt(strarray[1]);
                        log.info("小时分钟按冒号=====" + clock + min);
                        Date afterTime2 = getClockMinDate(clock, min);
                        log.info(String.valueOf(afterTime2));
                        int result = insert2Remind(afterTime2, things, uid, remindType);
                        String respone = "好的！我会在今天晚上" + clock + "点" + min + "分提醒你" + things;
                        return respone;
                    }
                }

            } else if (context.contains("明天")) {
                if (context.contains("上午")) {
                    if (context.contains("点")) {
                        if (context.contains("分")) {
                            Integer min = changeS2I(subString(context, "点", "分"));
                            Integer clock = changeS2I(subString(context, "上午", "点"));
                            log.info(min + clock + "===============");
                            Date afterTime2 = getClockMinDate2(clock, min, 0);
                            log.info(String.valueOf(afterTime2));
                            int result = insert2Remind(afterTime2, things, uid, remindType);
                            String respone = "好的！我会在明天上午" + clock + "点" + min + "分提醒你" + things;
                            return respone;
                        } else {
                            Integer clock = changeS2I(subString(context, "上午", "点提醒"));
                            Date afterTime2 = getClockDate2(clock, 0);
                            int result = insert2Remind(afterTime2, things, uid, remindType);
                            String respone = "好的！我会在明天上午" + clock + "点提醒你" + things;
                            return respone;
                        }
                    }
                    else if (context.contains(":")) {//时间格式为12:30
                        String time = subString(context, "上午", "提醒我");
                        String[] strarray = time.split(":");
                        int clock = Integer.parseInt(strarray[0]);
                        int min = Integer.parseInt(strarray[1]);
                        log.info("小时分钟按冒号=====" + clock + min);
                        Date afterTime2 = getClockMinDate2(clock, min, 0);
                        log.info(String.valueOf(afterTime2));
                        int result = insert2Remind(afterTime2, things, uid, remindType);
                        String respone = "好的！我会在明天上午" + clock + "点" + min + "分提醒你" + things;
                        return respone;
                    }
                } else if (context.contains("下午")) {
                    if (context.contains("点")) {
                        if (context.contains("分")) {
                            Integer min = changeS2I(subString(context, "点", "分"));
                            Integer clock = changeS2I(subString(context, "下午", "点"));
                            Date afterTime2 = getClockMinDate2(clock, min, 12);
                            int result = insert2Remind(afterTime2, things, uid, remindType);
                            String respone = "好的！我会在明天下午" + clock + "点" + min + "分提醒你" + things;
                            return respone;
                        } else {
                            Integer clock = changeS2I(subString(context, "下午", "点提醒"));
                            Date afterTime2 = getClockDate2(clock, 12);
                            int result = insert2Remind(afterTime2, things, uid, remindType);
                            String respone = "好的！我会在明天下午" + clock + "点提醒你" + things;
                            return respone;
                        }
                    }
                    else if (context.contains(":")) {//时间格式为12:30
                        String time = subString(context, "下午", "提醒我");
                        String[] strarray = time.split(":");
                        int clock = Integer.parseInt(strarray[0]);
                        int min = Integer.parseInt(strarray[1]);
                        log.info("小时分钟按冒号=====" + clock + min);
                        Date afterTime2 = getClockMinDate2(clock, min, 12);
                        log.info(String.valueOf(afterTime2));
                        int result = insert2Remind(afterTime2, things, uid, remindType);
                        String respone = "好的！我会在明天下午" + clock + "点" + min + "分提醒你" + things;
                        return respone;
                    }
                } else if (context.contains("晚上")) {
                    if (context.contains("点")) {
                        if (context.contains("分")) {
                            Integer min = changeS2I(subString(context, "点", "分"));
                            Integer clock = changeS2I(subString(context, "晚上", "点"));
                            log.info(min + clock + "===============");
                            Date afterTime2 = getClockMinDate2(clock, min, 12);
                            log.info(String.valueOf(afterTime2));
                            int result = insert2Remind(afterTime2, things, uid, remindType);
                            String respone = "好的！我会在明天晚上" + clock + "点" + min + "分提醒你" + things;
                            return respone;
                        } else {
                            Integer clock = changeS2I(subString(context, "晚上", "点提醒"));
                            Date afterTime2 = getClockDate2(clock, 12);
                            int result = insert2Remind(afterTime2, things, uid, remindType);
                            String respone = "好的！我会在明天晚上" + clock + "点提醒你" + things;
                            return respone;
                        }
                    }
                    else if (context.contains(":")) {//时间格式为12:30
                        String time = subString(context, "晚上", "提醒我");
                        String[] strarray = time.split(":");
                        int clock = Integer.parseInt(strarray[0]);
                        int min = Integer.parseInt(strarray[1]);
                        log.info("小时分钟按冒号=====" + clock + min);
                        Date afterTime2 = getClockMinDate2(clock, min, 12);
                        log.info(String.valueOf(afterTime2));
                        int result = insert2Remind(afterTime2, things, uid, remindType);
                        String respone = "好的！我会在明天晚上" + clock + "点" + min + "分提醒你" + things;
                        return respone;
                    }
                }
            }
        }

        return "添加没有成功哦！再试试吧！";


    }

    public static Date getClockMinDate(int clock, int min) {  //返回今天某点某分的time
        Calendar now = Calendar.getInstance();
        now.setTime(getStartOfDay(new Date()));
        now.set(Calendar.HOUR, now.get(Calendar.HOUR) + clock + 12);
        now.set(Calendar.MINUTE, now.get(Calendar.MINUTE) + min);
        return now.getTime();
    }

    public static Date getClockMinDate2(int clock, int min, int timeplus) {  //timeplus如果是下午或者晚上需要加12
        //返回明天某点的time
        Date date = new Date();//取时间
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(calendar.DATE, 1);//把日期往后增加一天.整数往后推,负数往前移动
        date = calendar.getTime(); //这个时间就是日期往后推一天的结果
        Calendar now = Calendar.getInstance();
        now.setTime(getStartOfDay(date));
        now.set(Calendar.HOUR, now.get(Calendar.HOUR) + clock + timeplus);
        now.set(Calendar.MINUTE, now.get(Calendar.MINUTE) + min);
        return now.getTime();
    }

    public int insert2Remind(Date afterTime, String things, String uid, Integer remindType) {
        Remind remind = new Remind();
        remind.setContent(things);
        remind.setTime(afterTime.toString());
        remind.setUid(uid);
        remind.setRemindtype(remindType);
        return remindMapper.insert(remind);
    }


    public String InsertDiary(String context, String uid) {
        if (context.contains("日记")) {
            Permanent permanent = new Permanent();
            permanent.setContent(context.substring(2));
            int happy = getSentiment(context.substring(2));
            permanent.setUid(uid);
            permanent.setTime(new Date().toString());
            permanent.setType(3);
            permanentMapper.insert(permanent);
            if (happy < 40) {
                return "您今天的日记已经存储好啦！您的心情指数是" + happy + "从主人的日记看，主人的心情不太好哦！这个世界虽然不完美，但总有人守护着你。";
            }
            if (happy > 70) {
                return "您今天的日记已经存储好啦！您的心情指数是" + happy + "小乔已经可以从主人的文字中感受到喜悦之情哦！希望主人天天这么开心！";
            } else {
                return "您今天的日记已经存储好啦！您的心情指数是" + happy + "平淡的一天，却是许多人不敢妄想的奢侈！要珍惜现在，活在当下哦！";
            }
        } else if (context.contains("电影")) {
            Permanent permanent = new Permanent();
            String[] a = context.split("电影");
            permanent.setUid(uid);
            permanent.setContent(a[1]);
            permanent.setTime(new Date().toString());
            permanent.setType(1);
            permanentMapper.insert(permanent);
            return "您今天看的电影小乔已经为您记下啦！";
        } else if (context.contains("工作记录")) {
            Permanent permanent = new Permanent();
            permanent.setUid(uid);
            permanent.setContent(context.substring(4));
            permanent.setTime(new Date().toString());
            permanent.setType(0);
            permanentMapper.insert(permanent);
            return "您的工作记录小乔已经为您记下啦！";
        } else if (context.contains("书")) {
            Permanent permanent = new Permanent();
            String[] a = context.split("书");
            permanent.setUid(uid);
            permanent.setContent(a[1]);
            permanent.setTime(new Date().toString());
            permanent.setType(2);
            permanentMapper.insert(permanent);
            return "您今天看的书小乔已经为您记下啦！读万卷书，行万里路";
        } else {
            return "虽然不知道你在说什么，但是肯定是有进步啦！加油！";
        }
    }


    public String InsertAccount(String context, String uid) {
        if (context.contains("元")) {
            context = context.substring(0, context.length() - 1);
            log.info(context);
        }
        if (context.contains("花了") || context.contains("支出")) {
            String keyWord = null;
            if (context.contains("花了")) {
                keyWord = "花了";
            } else {
                keyWord = "支出";
            }
            String[] output = context.split(keyWord);
            String things = output[0];
            Float money = Float.valueOf((output[1])) * -1;
            Date date = new Date();
            int type = 1;
            Ledger ledger = new Ledger();
            ledger.setContent(things);
            ledger.setEventtype(type);
            ledger.setMoney(money);
            ledger.setUid(uid);
            ledger.setDate(date.toString());
            ledgerMapper.insert(ledger);
        } else if (context.contains("收入") || context.contains("赚了")) {
            String keyWord = null;
            if (context.contains("收入")) {
                keyWord = "收入";
            } else {
                keyWord = "赚了";
            }
            String[] output = context.split(keyWord);
            String things = output[0];
            Float money = Float.valueOf((output[1]));
            Date date = new Date();
            int type = 2;
            Ledger ledger = new Ledger();
            ledger.setContent(things);
            ledger.setEventtype(type);
            ledger.setMoney(money);
            ledger.setUid(uid);
            ledger.setDate(date.toString());
            ledgerMapper.insert(ledger);
        } else if (context.contains("向我借了")) {
            String keyWord = null;
            if (context.contains("向我借了")) {
                keyWord = "向我借了";
            }
            if (context.endsWith("元")) {
                context = context.substring(0, context.length() - 1);
            }
            String[] output = context.split(keyWord);
            String things = context;
            Float money = Float.valueOf((output[1]));
            Date date = new Date();
            int type = 3;
            Ledger ledger = new Ledger();
            ledger.setContent(things);
            ledger.setEventtype(type);
            ledger.setMoney(money);
            ledger.setUid(uid);
            ledger.setDate(date.toString());
            ledgerMapper.insert(ledger);
        }
        return "收到！小乔为您记下了哦！";
    }

    public int getSentiment(String text) {
        //情感分析
        JSONObject res = aipNlpConfig.sentimentClassify(text);
        //获取items
        JSONArray items = res.getJSONArray("items");
        //取items的第一个元素，是个JSONObject对象
        JSONObject it1 = items.getJSONObject(0);
        //取it1的中属于积极类别的概率并 * 100
        int sentiment = (int) (it1.getDouble("positive_prob") * 100);
        return sentiment;
    }

    public String InsertBirthday(String context, String uid) {
        return null;
    }

    ;

    public String InsertCountdownDays(String context, String uid) {
        return null;
    }

    @Override
    public String InsertPeriod(String context, String uid) {
        Date date = new Date();
        Menstruation menstruation = new Menstruation();
        menstruation.setPeriod(date.toString());
        menstruation.setUid(uid);
        menstruation.setAdvance(3);
        menstruation.setLast("28");
        menstruationMapper.insert(menstruation);
        return "小乔为您记下了!下次姨妈来的前三天会提醒你哦!多喝红糖姜茶~~";
    }


    public String InsertPeriod(String context) {
        return null;
    }

    ;

    private Date timeChange(String time) throws ParseException {
        String sMonth = time.substring(0, time.indexOf("月"));//识别转换第几月
        int month = changeS2I(sMonth);
        String sdate = null;
        //识别转换第几天
        int date = 0;
        if (time.contains("日")) {
            sdate = subString(time, "月", "日");
            date = changeS2I(sdate);
        } else if (time.contains("号")) {
            sdate = subString(time, "月", "号");
            date = changeS2I(sdate);
        }
        //获取当前的时分秒作为详细参数（X天后的同一个时间）
        Calendar cal = Calendar.getInstance();
        int hour = cal.get(Calendar.HOUR_OF_DAY);//小时
        int minute = cal.get(Calendar.MINUTE);//分
        int second = cal.get(Calendar.SECOND);//秒
        String dateTime = getSysYear() + "-" + month + "-" + date + " " + hour + ":" + minute + ":" + second;
//  “2005-06-09 12:20:32”；
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date1 = format.parse(dateTime);
        return date1;
    }

    public static boolean isNumericZidai(String str) {
        for (int i = 0; i < str.length(); i++) {
            System.out.println(str.charAt(i));
            if (!Character.isDigit(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    public static String getSysYear() {

        Calendar date = Calendar.getInstance();

        String year = String.valueOf(date.get(Calendar.YEAR));

        return year;

    }


    public static String subString(String str, String strStart, String strEnd) {

        /* 找出指定的2个字符在 该字符串里面的 位置 */
        int strStartIndex = str.indexOf(strStart);
        int strEndIndex = str.indexOf(strEnd);

        /* index 为负数 即表示该字符串中 没有该字符 */
        if (strStartIndex < 0) {
            return "字符串 :---->" + str + "<---- 中不存在 " + strStart + ", 无法截取目标字符串";
        }
        if (strEndIndex < 0) {
            return "字符串 :---->" + str + "<---- 中不存在 " + strEnd + ", 无法截取目标字符串";
        }
        /* 开始截取 */
        String result = str.substring(strStartIndex, strEndIndex).substring(strStart.length());
        return result;
    }

    public static Integer changeS2I(String date) {
        if (isNumericZidai(date)) {  //如果是数字就直接变成数字
            return Integer.parseInt(date);
        } else {
            Map<String, Integer> map = new HashMap<String, Integer>();
            map.put("一", 1);
            map.put("二", 2);
            map.put("三", 3);
            map.put("四", 4);
            map.put("五", 5);
            map.put("六", 6);
            map.put("七", 7);
            map.put("八", 8);
            map.put("九", 9);
            map.put("十", 10);
            map.put("十一", 11);
            map.put("十二", 12);
            map.put("十三", 13);
            map.put("十四", 14);
            map.put("十五", 15);
            map.put("十六", 16);
            map.put("十七", 17);
            map.put("十八", 18);
            map.put("十九", 19);
            map.put("二十", 20);
            map.put("二十一", 21);
            map.put("二十二", 22);
            map.put("二十三", 23);
            map.put("二十四", 24);
            map.put("二十五", 25);
            map.put("二十六", 26);
            map.put("二十七", 27);
            map.put("二十八", 28);
            map.put("二十九", 29);
            map.put("三十", 30);
            map.put("三十一", 31);
            return map.get(date);
        }
    }

    public Date String2Week(String context) {
        Map<String, Integer> s2week = new HashMap<>();
        s2week.put("星期一", 2);
        s2week.put("星期二", 3);
        s2week.put("星期三", 4);
        s2week.put("星期四", 5);
        s2week.put("星期五", 6);
        s2week.put("星期六", 7);
        s2week.put("星期天", 8);
        s2week.put("周一", 2);
        s2week.put("周二", 3);
        s2week.put("周三", 4);
        s2week.put("周四", 5);
        s2week.put("周五", 6);
        s2week.put("周六", 7);
        s2week.put("周日", 8);
        int days = s2week.get(context);
        Calendar calendar = Calendar.getInstance();
        int day = calendar.get(Calendar.DAY_OF_WEEK);
        int time = days - day;//找出用户所说的那一天离今天有几天
        return getDateAfter(new Date(), time);
    }

    public static Date getDateAfter(Date d, int day) {   //获得day天后的日期
        Calendar now = Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.DATE, now.get(Calendar.DATE) + day);
        return now.getTime();
    }

    public static Date getClockDate(int clock) {  //返回今天某点的time
        Calendar now = Calendar.getInstance();
        now.setTime(getStartOfDay(new Date()));
        now.set(Calendar.HOUR, now.get(Calendar.HOUR) + clock + 12);
        return now.getTime();
    }

    public static Date getClockDate2(int clock, int timeplus) {  //timeplus如果是下午或者晚上需要加12
        //返回明天某点的time
        Date date = new Date();//取时间
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(calendar.DATE, 1);//把日期往后增加一天.整数往后推,负数往前移动
        date = calendar.getTime(); //这个时间就是日期往后推一天的结果
        Calendar now = Calendar.getInstance();
        now.setTime(getStartOfDay(date));
        now.set(Calendar.HOUR, now.get(Calendar.HOUR) + clock + timeplus);
        return now.getTime();
    }

    // 获得某天最小时间 2020-02-17 00:00:00
    public static Date getStartOfDay(Date date) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
        LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);
        return Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }

    public boolean IsNewUser(String uid) {
        if (userMapper.selectByPrimaryKey(uid) == null) {
            User user1 = new User();
            user1.setAlias("主人");
            user1.setUid(uid);
            user1.setAssistantname("小乔");
            userMapper.insert(user1);
        }
        return true;
    }
}
